package com.juejin.www.service.impl;

import com.alibaba.fastjson.JSON;
import com.juejin.www.dao.*;
import com.juejin.www.model.DO.Audit;
import com.juejin.www.model.DO.User;
import com.juejin.www.model.DTO.*;
import com.juejin.www.model.VO.AuditVO;
import com.juejin.www.service.AdminService;
import com.juejin.www.utils.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Jacky
 */
@Service
public class AdminServiceImpl implements AdminService {

    @Autowired
    private AdminDao adminDao;

    @Autowired
    private ArticleDao articleDao;

    @Autowired
    private BoilingPointDao boilingPointDao;

    @Autowired
    private NoticeDao noticeDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public PageDTO<AuditVO> getAudits(Integer currentPage,Integer pageSize,Integer isAudited) {
        Integer begin = (currentPage - 1) * pageSize;
        List<Audit> audits = adminDao.getAudits(begin, pageSize,isAudited);
        List<AuditVO> auditVos = audits.stream()
                .map(audit -> {
                    String type;
                    if(audit.getType()==1){
                        type="文章";
                    }else {
                        type="沸点";
                    }
                    String author = userDao.getById(audit.getAuthor()).getName();
                    String auditor=null;
                    if(isAudited==1){
                        auditor = userDao.getById(audit.getAuditor()).getName();
                    }
                    return new AuditVO(
                            audit.getId(),
                            audit.getTitle(),
                            audit.getContent(),
                            type,
                            author,
                            audit.getAuthor(),
                            audit.getIsAudited(),
                            auditor,
                            audit.getResult(),
                            audit.getOpinion(),
                            audit.getCreateTime(),
                            audit.getAuditTime()
                    );
                })
                .collect(Collectors.toList());
        Integer totalCount = adminDao.getAuditsTotalCount(isAudited);
        PageDTO<AuditVO> pageDTO = new PageDTO<>(totalCount,auditVos);
        return pageDTO;
    }

    @Override
    public Integer getIsNotAuditedCount() {
        Integer isNotAuditedCount = adminDao.getIsNotAuditedCount();
        return isNotAuditedCount;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void audit(AuditDTO auditDTO) {
        auditDTO.setAuditTime(LocalDateTime.now());
        adminDao.audit(auditDTO);
        Audit audit = adminDao.getById(auditDTO.getId());
        if(auditDTO.getResult()==1){
            NoticeDTO noticeDTO;
            if(audit.getType()==1){
                ArticleDTO articleDTO = new ArticleDTO(
                        audit.getTitle(),
                        audit.getContent(),
                        audit.getAuthor());
                articleDao.addArticle(articleDTO);
                noticeDTO = new NoticeDTO(
                        "您的文章审核通过,点击查看",
                        audit.getAuthor(),
                        audit.getId(),
                        LocalDateTime.now());
            }else {
                BoilingPointDTO boilingPointDTO = new BoilingPointDTO(
                        audit.getContent(),
                        audit.getAuthor());
                boilingPointDao.addBoilingPoint(boilingPointDTO);
                String key = "boilingPoints";
                String cacheValue = stringRedisTemplate.opsForValue().get(key);
                if(cacheValue!=null){
                    stringRedisTemplate.delete(key);
                }
                noticeDTO = new NoticeDTO(
                        "您的沸点审核通过,点击查看",
                        audit.getAuthor(),
                        audit.getId(),
                        LocalDateTime.now());
            }
            noticeDao.addNotice(noticeDTO);
        }else {
            NoticeDTO noticeDTO;
            if(audit.getType()==1){
                noticeDTO = new NoticeDTO(
                        "您的文章审核不通过，理由是：" + auditDTO.getOpinion(),
                        audit.getAuthor(),
                        audit.getId(),
                        LocalDateTime.now());
            }else {
                noticeDTO = new NoticeDTO(
                        "您的沸点审核不通过，理由是:" + auditDTO.getOpinion(),
                        audit.getAuthor(),
                        audit.getId(),
                        LocalDateTime.now());
            }
            noticeDao.addNotice(noticeDTO);
        }
    }

    @Override
    public void lockUser(Integer id) {
        adminDao.lockUser(id);
        String username = userDao.getUsername(id);
        String key = "user:"+username;
        String cacheValue = stringRedisTemplate.opsForValue().get(key);
        if(cacheValue!=null){
            stringRedisTemplate.delete(key);
        }
    }

    @Override
    public void unlockUser(Integer id) {
        adminDao.unlockUser(id);
        String username = userDao.getUsername(id);
        String key = "user:"+username;
        String cacheValue = stringRedisTemplate.opsForValue().get(key);
        if(cacheValue!=null){
            stringRedisTemplate.delete(key);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addAdmin(UserDTO userDTO) {
        String key = "user:"+userDTO.getUsername();
        String cacheValue = stringRedisTemplate.opsForValue().get(key);
        UserDTO u;
        if(cacheValue!=null){
            u = JSON.parseObject(cacheValue,UserDTO.class);
        }else {
            u = userDao.getByUsername(userDTO.getUsername());
        }
        if(u == null){
            //生成盐值
            String salt = MD5Util.generateSalt(8);

            //将密码和盐值合并。一起进行MD5加密
            String encrypt = MD5Util.encrypt(userDTO.getPassword() + salt);

            User user = new User();
            user.setUsername(userDTO.getUsername());
            user.setPassword(encrypt);
            user.setSalt(salt);
            user.setName(userDTO.getName());
            adminDao.addAdmin(user);
            userDao.insertRelUserRole(userDao.getByUsername(userDTO.getUsername()).getId(),3);
            return true;
        }else {
            return false;
        }
    }
}
